﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Unis.Framework.Core.Utility;
using Unis.Framework.ORM.Common;
using Unis.Framework.ORM.Emit;
using Unis.Framework.ORM.Mapping;
using Unis.Framework.ORM.Model;
using Unis.Framework.RuleBase.Common;
using Unis.ORM.Mapping;
using Unis.RuleBase.Common;
using Unis.RuleBase.IFace;

namespace Unis.Framework.RuleBase
{
    public abstract class BaseRule : BaseQueryRule, IBaseRule, IBaseQueryRule, IDisposable
    {
        // Fields
        private ObjectDataList _ObjectDataList;
        private QueryParameterMappings _QueryParamMapping;

        // Methods
        public BaseRule(Type objectDataDocType)
            : base(objectDataDocType)
        {
        }

        public virtual int AddToCache(int dataInDocType, object entity, bool isDelete, string[] propertys)
        {
            if (this._ObjectDataList == null)
            {
                this._ObjectDataList = new ObjectDataList();
            }
            ObjectDataInfo dataInfo = new ObjectDataInfo(base.ConvertDataInDocType(dataInDocType), entity)
            {
                SavePropertys = propertys
            };
            if (isDelete)
            {
                dataInfo.DataState = ObjectDataState.Deleted;
                if (entity.GetType().IsSubclassOf(typeof(BaseModel)))
                {
                    (entity as BaseModel).EntityState = EntityState.Deleted;
                }
            }
            this._ObjectDataList.Add(dataInfo);
            return 1;
        }

        protected virtual void BatchSettingNewEntityID(int dataInDocType)
        {
            IEnumerable<object> source = from item in this._ObjectDataList.Values
                                         where ((item.ObjectData is BaseModel) && (((BaseModel)item.ObjectData).EntityState == EntityState.New)) && (((int)item.DataInDocType) == dataInDocType)
                                         select item.ObjectData;
            int count = source.Count<object>();
            if (count > 0)
            {
                List<string> createNewEntityIds = this.GetCreateNewEntityIds(count);
                DynamicPropertyAccessor accessor = new DynamicPropertyAccessor(source.First<object>().GetType(), "ID");
                int i = 0;
                foreach (object obj2 in source)
                {
                    accessor.Set(obj2, createNewEntityIds[i]);
                    i++;
                }
            }
        }

        public virtual bool CheckValueIsExists(int dataInDocType, object entity, string[] checkPropertys)
        {
            return new ObjectDataValidatedHelper().CheckValueIsExists(base.ConvertDataInDocType(dataInDocType), entity, checkPropertys);
        }

        public virtual object CreateNewEntity(int dataInDocType)
        {
            return new ObjectEditHelper().CreateNewEntity(this, base.ConvertDataInDocType(dataInDocType));
        }

        public virtual IList CreateNewEntityBatch(int dataInDocType, int createCount)
        {
            return new ObjectEditHelper().CreateNewEntityBatch(this, base.ConvertDataInDocType(dataInDocType), createCount);
        }

        public virtual int DeletedImmediate(int dataInDocType, object key)
        {
            return new ObjectEditHelper().DeletedImmediate(this, base.ConvertDataInDocType(dataInDocType), key);
        }

        public virtual int Flush()
        {
            if (this._ObjectDataList == null)
            {
                return 0;
            }
            int num = new ObjectEditHelper().SaveObjectDataList(this, this._ObjectDataList);
            if (num > 0)
            {
                this._ObjectDataList.Clear();
            }
            return num;
        }

        public virtual string GetCreateNewEntityId()
        {
            //ObjectDataMappingAttribute objectDataMappingAttribute = AttributeConfigHelper.Instance.GetObjectDataMappingAttribute(base.ConvertDataInDocType(dataInDocType));
            //if (objectDataMappingAttribute == null)
            //{
            //    throw new RequireConfigDataMappingException(base.ConvertDataInDocType(dataInDocType));
            //}
            //if (!objectDataMappingAttribute.KeyIsSelfAdd)
            //{
            //    return 0;
            //}
            //return EntityIdentityHelper.NewInstance.GetEntityIdentity(objectDataMappingAttribute.MappingTableName, count);
            return Guid.NewGuid().ToString().ToUpper();
        }

        public virtual List<string> GetCreateNewEntityIds(int count)
        {
            List<string> list = new List<string>();
            for (int i = 0; i < count; i++)
            {
                list.Add(Guid.NewGuid().ToString().ToUpper());
            }
            return list;
        }

        public virtual object GetObjectByKey(int dataInDocType, object keyValue)
        {
            return new ObjectEditHelper().GetObjectByKey<object>(this, base.ConvertDataInDocType(dataInDocType), keyValue);
        }

        public virtual object RefreshEntity(int dataInDocType, object entity)
        {
            return new ObjectEditHelper().RefreshEntity(this, base.ConvertDataInDocType(dataInDocType), entity, new object[0]);
        }

       
        public virtual int SaveDataSetImmediate(DataSet dsData, int dataInDocType)
        {
            return new ObjectEditHelper().SaveDataSetImmediate(this, base.ConvertDataInDocType(dataInDocType), dsData);
        }

      
        public virtual int Submit(object entity, bool cancelSubmit)
        {
            //if (cancelSubmit)
            //{
            //    ObjectSubmitHelper.NewInstance.ObjectCancelSubmit(this, entity);
            //}
            //else
            //{
            //    ObjectSubmitHelper.NewInstance.ObjectSubmit(this, entity);
            //}
            return 1;
        }

        // Properties
        protected ObjectDataList CurrentDataList
        {
            get
            {
                return this._ObjectDataList;
            }
        }

        public virtual void Dispose()
        { }
    }
}
